﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OAuth;
using DotNetOpenAuth.OAuth.ChannelElements;

namespace OrkutAPILibrary
{
    /// <summary>
    /// The Orkut Consumer class
    /// </summary>
    public static class OrkutConsumer
    {
        /// <summary>
        /// The Consumer to use for accessing Google data APIs.
        /// </summary>
        public static readonly ServiceProviderDescription ServiceDescription = new ServiceProviderDescription
        {
            RequestTokenEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
            UserAuthorizationEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthAuthorizeToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
            AccessTokenEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetAccessToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
            TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
        };

        /// <summary>
        /// The service description to use for accessing Google data APIs using an X509 certificate.
        /// </summary>
        /// <param name="signingCertificate">The signing certificate.</param>
        /// <returns>A service description that can be used to create an instance of
        /// <see cref="DesktopConsumer"/> or <see cref="WebConsumer"/>. </returns>
        public static ServiceProviderDescription CreateRsaSha1ServiceDescription(X509Certificate2 signingCertificate)
        {
            if (signingCertificate == null)
            {
                throw new ArgumentNullException("signingCertificate");
            }

            return new ServiceProviderDescription
            {
                RequestTokenEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetRequestToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
                UserAuthorizationEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthAuthorizeToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
                AccessTokenEndpoint = new MessageReceivingEndpoint("https://www.google.com/accounts/OAuthGetAccessToken", HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.GetRequest),
                TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new RsaSha1SigningBindingElement(signingCertificate) },
            };
        }

        /// <summary>
        /// Requests authorization from Google to access data from a set of Google applications.
        /// </summary>
        /// <param name="consumer">The consumer.</param>
        public static void RequestAuthorization(WebConsumer consumer)
        {
            if (consumer == null)
            {
                throw new ArgumentNullException("consumer");
            }

            var extraParameters = new Dictionary<string, string> {
				{ "scope", "http://orkut.gmodules.com/social" },
			};
            Uri callback = Util.GetCallbackUrlFromContext();
            var request = consumer.PrepareRequestUserAuthorization(callback, extraParameters, null);
            consumer.Channel.Send(request);
        }

        /// <summary>
        /// Requests authorization from Google to access data from a set of Google applications.
        /// </summary>
        /// <param name="consumer">The consumer.</param>
        /// <param name="requestToken">The unauthorized request token assigned by Google.</param>
        /// <returns>The request token</returns>
        public static Uri RequestAuthorization(DesktopConsumer consumer, out string requestToken)
        {
            if (consumer == null)
            {
                throw new ArgumentNullException("consumer");
            }

            var extraParameters = new Dictionary<string, string> {
				{ "scope", "http://orkut.gmodules.com/social" },
			};

            return consumer.RequestUserAuthorization(extraParameters, null, out requestToken);
        }
    }
}
